#ifndef A8_CSVREADER_H
#define A8_CSVREADER_H

#include <string>
#include <map>
#include <vector>
#include <a8/xvalue.hpp>
#include <a8/strutils.hpp>
#include <a8/stringlist.hpp>

namespace a8
{
	class CsvReader
	{
	public:
		CsvReader():mCurrLine(0)
		{
		}

		bool Load(const std::string& filename)
		{
			mColumns.clear();
			mValues.clear();
			mCurrLine = 0;
			bool ret = mStringList.LoadFromFile(filename.c_str());
			if(ret){
				if(NextLine()){
					for(int i = 0;i < mValues.size(); i++){
						mColumns.insert(std::pair<std::string, int>(mValues[i], i));
					}
				}
			}
			return ret;
		}

		bool NextLine()
		{
			if(mCurrLine >= mStringList.Count()){
				return false;
			}
			mValues.clear();
			const char *p  = mStringList.String(mCurrLine).c_str();
			const char *pv = p;
			//			printf("%s\n", p);
			while(*p && p){
				if(*p == ','){
					if(p > pv){
						mValues.push_back(std::string(pv, p - pv));
						//						printf("%s\n", std::string(pv, p - pv).c_str());
					}else{
						mValues.push_back("");
					}
					pv = p + 1;
				}
				p++;
			}
			if(p && *p  == ','){
				mValues.push_back("");
			}else if(p > pv){
				mValues.push_back(std::string(pv, p - pv));
			}
			if(mColumns.size() - mValues.size() == 1){
				mValues.push_back("");
			}
			if(mColumns.size() > 0){
				assert(mValues.size() >= mColumns.size());
			}
			mCurrLine++;
			return true;
		}

		a8::XValue GetValue(const char* name)
		{
			std::map<std::string, int>::iterator itr = mColumns.find(name);
			if(itr != mColumns.end()){
				std::string decoestring = mValues[itr->second];
				a8::replace_string(decoestring, "\\n", "\n");
				return a8::XValue(decoestring);
			}else{
				assert(false);
				return a8::XValue("");
			}
		}

		a8::XValue GetValue(const std::string& name)
		{
			return GetValue(name.c_str());
		}

		bool KeyExists(const std::string& name)
		{
			auto itr = mColumns.find(name);
			return itr != mColumns.end();
		}

	private:
		std::map<std::string, int> mColumns;
		std::vector<std::string> mValues;

		int mCurrLine;
		a8::StringList mStringList;
	};
}

#endif
